package com.jetpack.mvvm.lib.base.extention

import android.app.Activity
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty

/**
 * 提供通过 intent/bundle 获取对应 key 对应的 value 的功能的简洁函数
 */

fun <T> extraActivity(name: String): ActivityExtras<T?> = ActivityExtras(name, null)

fun <T> extraActivity(name: String, defaultValue: T) = ActivityExtras(name, defaultValue)

fun <T> extraFragment(name: String): FragmentExtras<T?> = FragmentExtras(name, null)

fun <T> extraFragment(name: String, defaultValue: T) = FragmentExtras(name, defaultValue)


class ActivityExtras<T>(private val name: String, private val defaultValue: T) :
    ReadOnlyProperty<Activity, T?> {

    private var extra: T? = null
    private var hasSet = false

    override fun getValue(thisRef: Activity, property: KProperty<*>): T? {
        if (hasSet) {
            return extra
        }
        hasSet = true
        return extra
            ?: thisRef.intent?.extras?.take<T>(name)?.also { extra = it }
            ?: defaultValue.also { extra = it }
    }
}


class FragmentExtras<T>(private val name: String, private val defaultValue: T) :
    ReadOnlyProperty<Fragment, T> {

    private var extra: T? = null
    private var hasSet = false

    override fun getValue(thisRef: Fragment, property: KProperty<*>): T {
        if (hasSet) {
            return extra ?: defaultValue
        }
        hasSet = true
        return extra
            ?: thisRef.arguments?.take<T>(name)?.also { extra = it }
            ?: defaultValue.also { extra = it }
    }
}


@Suppress("UNCHECKED_CAST")
fun <T> Bundle.take(key: String): T? {
    try {
        return get(key) as? T
    } catch (e: Exception) {
        e.printStackTrace()
    }
    return null
}